<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>FLV视频流播放器</title>
    <script src="./flv.min.js"></script>
    <style>
      body {
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 20px;
        background-color: #f5f5f5;
      }
      .container {
        max-width: 800px;
        margin: 0 auto;
        background-color: white;
        padding: 20px;
        border-radius: 8px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      }
      h1 {
        color: #333;
        text-align: center;
      }
      .input-group {
        margin-bottom: 20px;
      }
      label {
        display: block;
        margin-bottom: 5px;
        font-weight: bold;
      }
      input {
        width: 100%;
        padding: 8px;
        box-sizing: border-box;
        border: 1px solid #ddd;
        border-radius: 4px;
      }
      button {
        background-color: #4caf50;
        color: white;
        border: none;
        padding: 10px 20px;
        cursor: pointer;
        border-radius: 4px;
        font-size: 16px;
      }
      button:hover {
        background-color: #45a049;
      }
      #video-container {
        position: relative;
        width: 100%;
        height: 500px;
        background-color: #000;
        border-radius: 4px;
        overflow: hidden;
      }
      video {
        width: 100%;
        height: 500px;
        display: block;
      }
      #status {
        margin-top: 10px;
        padding: 10px;
        background-color: #f8f8f8;
        border-radius: 4px;
        font-size: 14px;
      }
      .error {
        color: red;
      }
      .success {
        color: green;
      }
      .loading {
        color: blue;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h1>FLV视频流播放器</h1>
      <div class="input-group">
        <label for="videoUrl">视频URL：</label>
        <input
          type="text"
          id="videoUrl"
          placeholder="输入FLV视频URL"
          value="https://video-tongli.seazonmotor.com:9994/gps-web/photos?refPath=2025-11-10/179/172836_02_65_6505_0_13111107002-20251110172836-11409.h265&push=true"
        />
      </div>

      <button id="playBtn">播放</button>
      <button id="stopBtn" disabled>停止</button>

      <div id="video-container">
        <video id="videoElement" controls autoplay></video>
      </div>

      <div id="status">等待播放...</div>
    </div>

    <script>
      // 获取DOM元素
      const videoElement = document.getElementById('videoElement');
      const videoUrlInput = document.getElementById('videoUrl');
      const playBtn = document.getElementById('playBtn');
      const stopBtn = document.getElementById('stopBtn');
      const statusElement = document.getElementById('status');

      let flvPlayer = null;
      let ws = null;

      // 更新状态信息
      function updateStatus(message, type = 'info') {
        statusElement.textContent = message;
        statusElement.className = '';
        if (type) {
          statusElement.classList.add(type);
        }
      }

      // 停止当前播放
      function stopPlayback() {
        // 停止FLV播放器
        if (flvPlayer) {
          flvPlayer.destroy();
          flvPlayer = null;
        }

        // 关闭WebSocket连接
        if (ws && ws.readyState === WebSocket.OPEN) {
          ws.close();
          ws = null;
        }

        // 更新UI
        playBtn.disabled = false;
        stopBtn.disabled = true;
        updateStatus('已停止播放', 'info');
      }

      // 初始化播放器
      function initPlayer() {
        if (flvjs.isSupported()) {
          updateStatus('正在准备播放器...', 'loading');

          // 获取视频URL
          const videoUrl = videoUrlInput.value.trim();

          // 创建FLV播放器实例
          flvPlayer = flvjs.createPlayer({
            type: 'flv',
            url: videoUrl,
            isLive: true, // 标记为直播流
            hasAudio: false,
            hasVideo: true,
          });

          flvPlayer.attachMediaElement(videoElement);

          flvPlayer.on(flvjs.Events.METADATA_LOADED, () => {
            updateStatus('视频元数据已加载', 'success');
            attemptPlay();
          });

          // 加载视频
          flvPlayer.load();

          flvPlayer.on(flvjs.Events.ERROR, (err, detail) => {
            console.error('FLV播放器错误:', err, detail);
            let errorMsg = '播放出错';

            switch (err) {
              case flvjs.ErrorTypes.NETWORK_ERROR:
                errorMsg = '网络错误，请检查连接';
                break;
              case flvjs.ErrorTypes.MEDIA_ERROR:
                errorMsg = '媒体解码错误';
                break;
              case flvjs.ErrorTypes.OTHER_ERROR:
                errorMsg = '其他错误';
                break;
            }

            updateStatus(`${errorMsg}: ${detail}`, 'error');

            // 尝试自动恢复播放
            setTimeout(() => {
              updateStatus('尝试恢复播放...', 'loading');
              if (flvPlayer) {
                attemptPlay();
              }
            }, 2000);
          });

          flvPlayer.on(flvjs.Events.LOADING_COMPLETE, () => {
            updateStatus('视频加载完成', 'info');
          });

          flvPlayer.on(flvjs.Events.LOADING_PROGRESS, () => {
            updateStatus('视频加载中...', 'loading');
          });

          function attemptPlay() {
            if (!flvPlayer) return;

            flvPlayer
              .play()
              .then(() => {
                updateStatus('视频播放中', 'success');
                playBtn.disabled = true;
                stopBtn.disabled = false;
              })
              .catch((error) => {
                console.error('播放失败:', error);
                // 处理自动播放限制错误
                if (
                  error.name === 'NotAllowedError' ||
                  error.message.includes('interrupted by a call to pause()') ||
                  error.message.includes('user gesture')
                ) {
                  updateStatus(
                    '请点击视频区域手动开始播放，浏览器限制自动播放',
                    'info',
                  );
                  // 提示用户手动点击播放
                  videoElement.addEventListener('click', handleVideoClick, {
                    once: true,
                  });
                } else {
                  updateStatus(`播放失败: ${error.message}`, 'error');
                }
              });
          }

          function handleVideoClick() {
            attemptPlay();
          }

          // 如果URL是WebSocket类型，需要特殊处理
          if (videoUrl.startsWith('ws://') || videoUrl.startsWith('wss://')) {
            // 创建WebSocket连接
            ws = new WebSocket(videoUrl);

            // WebSocket消息处理
            ws.onmessage = (event) => {
              if (
                event.data instanceof ArrayBuffer ||
                event.data instanceof Blob
              ) {
                // 将接收到的FLV数据传递给flv.js处理
                if (flvPlayer) {
                  flvPlayer.feed(event.data);
                }
              }
            };

            // WebSocket连接打开
            ws.onopen = () => {
              updateStatus(
                'WebSocket连接已建立，正在接收FLV视频流...',
                'success',
              );
            };

            // WebSocket错误
            ws.onerror = (error) => {
              updateStatus(
                `WebSocket连接错误: ${error.message || '未知错误'}`,
                'error',
              );
            };

            // WebSocket连接关闭
            ws.onclose = () => {
              updateStatus('WebSocket连接已关闭', 'info');
              // 延迟停止，让缓冲区的内容播放完
              setTimeout(() => {
                if (flvPlayer) {
                  stopPlayback();
                }
              }, 3000);
            };
          }
        } else {
          updateStatus('您的浏览器不支持FLV.js', 'error');
          playBtn.disabled = true;
        }
      }

      // 事件监听
      playBtn.addEventListener('click', () => {
        const videoUrl = videoUrlInput.value.trim();
        if (!videoUrl) {
          updateStatus('请输入视频URL', 'error');
          return;
        }

        // 先停止当前播放
        stopPlayback();

        // 初始化新播放
        initPlayer();
      });

      stopBtn.addEventListener('click', stopPlayback);

      // 页面卸载时清理资源
      window.addEventListener('beforeunload', () => {
        stopPlayback();
      });

      // 页面加载时检查FLV.js支持
      window.addEventListener('load', () => {
        if (!flvjs.isSupported()) {
          updateStatus(
            '您的浏览器不支持FLV.js，请使用Chrome、Firefox等现代浏览器',
            'error',
          );
          playBtn.disabled = true;
        }
      });
    </script>
  </body>
</html>
